from PySide6.QtCore import Signal, QTimer
from PySide6.QtGui import QTextCursor
from loguru import logger
from datetime import datetime

from ui.components.base.widget import TgBaseWidget
from ui.components.inputs.text_edit import TgTextEdit
from ui.components.layouts.vbox_layout import TgVBoxLayout


class LogBox(TgBaseWidget):
    """A widget for displaying logs with thread-safe updates."""
    
    log_update_signal = Signal(str)

    def __init__(self, placeholder_text: str = "Logs will be displayed here..."):
        super().__init__()
        self.setFixedHeight(150)
        
        layout = TgVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)

        self.log_display = TgTextEdit(placeholder_text=placeholder_text)
        self.log_display.setReadOnly(True)
        
        layout.addWidget(self.log_display)
        
        self.log_update_signal.connect(self._update_log_display)

    def log(self, message: str):
        """
        Logs a message. Can be called from any thread.
        Prepends a timestamp to the message.
        """
        try:
            timestamp = datetime.now().strftime("%H:%M:%S")
            formatted_message = f"[{timestamp}] {message}"
            self.log_update_signal.emit(formatted_message)
        except Exception as e:
            logger.exception(f"Error in log callback: {e}")

    def append(self, message: str):
        """
        Appends a raw message to the log display. Must be called from the main GUI thread.
        """
        self._update_log_display(message)

    def clear(self):
        """Clears the log display."""
        self.log_display.clear()

    def _update_log_display(self, formatted_message: str):
        """Updates the log display (slot)."""
        try:
            self.log_display.append(formatted_message)
            self._scroll_log_to_bottom()
        except Exception as e:
            logger.exception(f"Error updating log display: {e}")

    def _scroll_log_to_bottom(self):
        """Scrolls the log display to the bottom."""
        try:
            cursor = self.log_display.textCursor()
            cursor.movePosition(QTextCursor.MoveOperation.End)
            self.log_display.setTextCursor(cursor)
            self._process_ui_events()
        except Exception as e:
            logger.exception(f"Error scrolling log to bottom: {e}")
            
    def _process_ui_events(self):
        """Process UI events to ensure the interface remains responsive."""
        try:
            from PySide6.QtCore import QCoreApplication
            QCoreApplication.processEvents()
        except Exception as e:
            logger.exception(f"Error processing UI events: {e}")
